mirror of
https://github.com/sysprog21/lkmpg.git
synced 2024-11-25 09:01:26 +08:00
Fix the warnings raised by Sparse (#92)
Sparse[1] is a semantic parser, capable of finding out the potential problems of Linux kernel code. This patch fixed the warnings. [1] https://www.kernel.org/doc/html/latest/dev-tools/sparse.html
This commit is contained in:
parent
21ca08a17e
commit
9289bfe59c
|
@ -45,7 +45,7 @@ static void bottomhalf_tasklet_fn(unsigned long data)
|
||||||
pr_info("Bottom half tasklet ends\n");
|
pr_info("Bottom half tasklet ends\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_TASKLET_OLD(buttontask, bottomhalf_tasklet_fn);
|
static DECLARE_TASKLET_OLD(buttontask, bottomhalf_tasklet_fn);
|
||||||
|
|
||||||
/* interrupt function triggered when a button is pressed */
|
/* interrupt function triggered when a button is pressed */
|
||||||
static irqreturn_t button_isr(int irq, void *data)
|
static irqreturn_t button_isr(int irq, void *data)
|
||||||
|
|
|
@ -16,8 +16,9 @@
|
||||||
/* Prototypes - this would normally go in a .h file */
|
/* Prototypes - this would normally go in a .h file */
|
||||||
static int device_open(struct inode *, struct file *);
|
static int device_open(struct inode *, struct file *);
|
||||||
static int device_release(struct inode *, struct file *);
|
static int device_release(struct inode *, struct file *);
|
||||||
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
|
static ssize_t device_read(struct file *, char __user *, size_t, loff_t *);
|
||||||
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
|
static ssize_t device_write(struct file *, const char __user *, size_t,
|
||||||
|
loff_t *);
|
||||||
|
|
||||||
#define SUCCESS 0
|
#define SUCCESS 0
|
||||||
#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */
|
#define DEVICE_NAME "chardev" /* Dev name as it appears in /proc/devices */
|
||||||
|
@ -105,7 +106,7 @@ static int device_release(struct inode *inode, struct file *file)
|
||||||
* read from it.
|
* read from it.
|
||||||
*/
|
*/
|
||||||
static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */
|
static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */
|
||||||
char *buffer, /* buffer to fill with data */
|
char __user *buffer, /* buffer to fill with data */
|
||||||
size_t length, /* length of the buffer */
|
size_t length, /* length of the buffer */
|
||||||
loff_t *offset)
|
loff_t *offset)
|
||||||
{
|
{
|
||||||
|
@ -134,8 +135,8 @@ static ssize_t device_read(struct file *filp, /* see include/linux/fs.h */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when a process writes to dev file: echo "hi" > /dev/hello */
|
/* Called when a process writes to dev file: echo "hi" > /dev/hello */
|
||||||
static ssize_t device_write(struct file *filp, const char *buff, size_t len,
|
static ssize_t device_write(struct file *filp, const char __user *buff,
|
||||||
loff_t *off)
|
size_t len, loff_t *off)
|
||||||
{
|
{
|
||||||
pr_alert("Sorry, this operation is not supported.\n");
|
pr_alert("Sorry, this operation is not supported.\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -121,9 +121,10 @@ static ssize_t device_write(struct file *file, const char __user *buffer,
|
||||||
* If the ioctl is write or read/write (meaning output is returned to the
|
* If the ioctl is write or read/write (meaning output is returned to the
|
||||||
* calling process), the ioctl call returns the output of this function.
|
* calling process), the ioctl call returns the output of this function.
|
||||||
*/
|
*/
|
||||||
long device_ioctl(struct file *file, /* ditto */
|
static long
|
||||||
unsigned int ioctl_num, /* number and param for ioctl */
|
device_ioctl(struct file *file, /* ditto */
|
||||||
unsigned long ioctl_param)
|
unsigned int ioctl_num, /* number and param for ioctl */
|
||||||
|
unsigned long ioctl_param)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *temp;
|
char *temp;
|
||||||
|
@ -139,23 +140,23 @@ long device_ioctl(struct file *file, /* ditto */
|
||||||
temp = (char *)ioctl_param;
|
temp = (char *)ioctl_param;
|
||||||
|
|
||||||
/* Find the length of the message */
|
/* Find the length of the message */
|
||||||
get_user(ch, temp);
|
get_user(ch, (char __user *)temp);
|
||||||
for (i = 0; ch && i < BUF_LEN; i++, temp++)
|
for (i = 0; ch && i < BUF_LEN; i++, temp++)
|
||||||
get_user(ch, temp);
|
get_user(ch, (char __user *)temp);
|
||||||
|
|
||||||
device_write(file, (char *)ioctl_param, i, 0);
|
device_write(file, (char __user *)ioctl_param, i, NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_GET_MSG:
|
case IOCTL_GET_MSG:
|
||||||
/* Give the current message to the calling process - the parameter
|
/* Give the current message to the calling process - the parameter
|
||||||
* we got is a pointer, fill it.
|
* we got is a pointer, fill it.
|
||||||
*/
|
*/
|
||||||
i = device_read(file, (char *)ioctl_param, 99, 0);
|
i = device_read(file, (char __user *)ioctl_param, 99, NULL);
|
||||||
|
|
||||||
/* Put a zero at the end of the buffer, so it will be properly
|
/* Put a zero at the end of the buffer, so it will be properly
|
||||||
* terminated.
|
* terminated.
|
||||||
*/
|
*/
|
||||||
put_user('\0', (char *)ioctl_param + i);
|
put_user('\0', (char __user *)ioctl_param + i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_GET_NTH_BYTE:
|
case IOCTL_GET_NTH_BYTE:
|
||||||
|
@ -176,7 +177,7 @@ long device_ioctl(struct file *file, /* ditto */
|
||||||
* is kept in the devices table, it can't be local to init_module. NULL is
|
* is kept in the devices table, it can't be local to init_module. NULL is
|
||||||
* for unimplemented functions.
|
* for unimplemented functions.
|
||||||
*/
|
*/
|
||||||
struct file_operations fops = {
|
static struct file_operations fops = {
|
||||||
.read = device_read,
|
.read = device_read,
|
||||||
.write = device_write,
|
.write = device_write,
|
||||||
.unlocked_ioctl = device_ioctl,
|
.unlocked_ioctl = device_ioctl,
|
||||||
|
|
|
@ -61,7 +61,7 @@ ERROR_THREAD_1:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void completions_exit(void)
|
static void completions_exit(void)
|
||||||
{
|
{
|
||||||
wait_for_completion(&machine.crank_comp);
|
wait_for_completion(&machine.crank_comp);
|
||||||
wait_for_completion(&machine.flywheel_comp);
|
wait_for_completion(&machine.flywheel_comp);
|
||||||
|
|
|
@ -18,7 +18,7 @@ static void show_hash_result(char *plaintext, char *hash_sha256)
|
||||||
pr_info("%s\n", str);
|
pr_info("%s\n", str);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cryptosha256_init(void)
|
static int cryptosha256_init(void)
|
||||||
{
|
{
|
||||||
char *plaintext = "This is a test";
|
char *plaintext = "This is a test";
|
||||||
char hash_sha256[SHA256_LENGTH];
|
char hash_sha256[SHA256_LENGTH];
|
||||||
|
@ -53,7 +53,7 @@ int cryptosha256_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cryptosha256_exit(void)
|
static void cryptosha256_exit(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cryptoapi_init(void)
|
static int cryptoapi_init(void)
|
||||||
{
|
{
|
||||||
/* The world's favorite password */
|
/* The world's favorite password */
|
||||||
char *password = "password123";
|
char *password = "password123";
|
||||||
|
@ -186,7 +186,7 @@ int cryptoapi_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cryptoapi_exit(void)
|
static void cryptoapi_exit(void)
|
||||||
{
|
{
|
||||||
test_skcipher_finish(&sk);
|
test_skcipher_finish(&sk);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
DEFINE_MUTEX(mymutex);
|
static DEFINE_MUTEX(mymutex);
|
||||||
|
|
||||||
static int example_mutex_init(void)
|
static int example_mutex_init(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
DEFINE_RWLOCK(myrwlock);
|
static DEFINE_RWLOCK(myrwlock);
|
||||||
|
|
||||||
static void example_read_lock(void)
|
static void example_read_lock(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
|
||||||
DEFINE_SPINLOCK(sl_static);
|
static DEFINE_SPINLOCK(sl_static);
|
||||||
spinlock_t sl_dynamic;
|
static spinlock_t sl_dynamic;
|
||||||
|
|
||||||
static void example_spinlock_static(void)
|
static void example_spinlock_static(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@ static void tasklet_fn(unsigned long data)
|
||||||
pr_info("Example tasklet ends\n");
|
pr_info("Example tasklet ends\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
DECLARE_TASKLET_OLD(mytask, tasklet_fn);
|
static DECLARE_TASKLET_OLD(mytask, tasklet_fn);
|
||||||
|
|
||||||
static int example_tasklet_init(void)
|
static int example_tasklet_init(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,8 +86,8 @@ done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t test_ioctl_read(struct file *filp, char __user *buf, size_t count,
|
static ssize_t test_ioctl_read(struct file *filp, char __user *buf,
|
||||||
loff_t *f_pos)
|
size_t count, loff_t *f_pos)
|
||||||
{
|
{
|
||||||
struct test_ioctl_data *ioctl_data = filp->private_data;
|
struct test_ioctl_data *ioctl_data = filp->private_data;
|
||||||
unsigned char val;
|
unsigned char val;
|
||||||
|
@ -139,7 +139,7 @@ static int test_ioctl_open(struct inode *inode, struct file *filp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct file_operations fops = {
|
static struct file_operations fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = test_ioctl_open,
|
.open = test_ioctl_open,
|
||||||
.release = test_ioctl_close,
|
.release = test_ioctl_close,
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
|
|
||||||
MODULE_DESCRIPTION("Example module illustrating the use of Keyboard LEDs.");
|
MODULE_DESCRIPTION("Example module illustrating the use of Keyboard LEDs.");
|
||||||
|
|
||||||
struct timer_list my_timer;
|
static struct timer_list my_timer;
|
||||||
struct tty_driver *my_driver;
|
static struct tty_driver *my_driver;
|
||||||
char kbledstatus = 0;
|
static char kbledstatus = 0;
|
||||||
|
|
||||||
#define BLINK_DELAY HZ / 5
|
#define BLINK_DELAY HZ / 5
|
||||||
#define ALL_LEDS_ON 0x07
|
#define ALL_LEDS_ON 0x07
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
|
|
||||||
#define procfs_name "helloworld"
|
#define procfs_name "helloworld"
|
||||||
|
|
||||||
struct proc_dir_entry *our_proc_file;
|
static struct proc_dir_entry *our_proc_file;
|
||||||
|
|
||||||
ssize_t procfile_read(struct file *filePointer, char *buffer,
|
static ssize_t procfile_read(struct file *filePointer, char __user *buffer,
|
||||||
size_t buffer_length, loff_t *offset)
|
size_t buffer_length, loff_t *offset)
|
||||||
{
|
{
|
||||||
char s[13] = "HelloWorld!\n";
|
char s[13] = "HelloWorld!\n";
|
||||||
int len = sizeof(s);
|
int len = sizeof(s);
|
||||||
|
|
|
@ -25,8 +25,8 @@ static char procfs_buffer[PROCFS_MAX_SIZE];
|
||||||
static unsigned long procfs_buffer_size = 0;
|
static unsigned long procfs_buffer_size = 0;
|
||||||
|
|
||||||
/* This function is called then the /proc file is read */
|
/* This function is called then the /proc file is read */
|
||||||
ssize_t procfile_read(struct file *filePointer, char *buffer,
|
static ssize_t procfile_read(struct file *filePointer, char __user *buffer,
|
||||||
size_t buffer_length, loff_t *offset)
|
size_t buffer_length, loff_t *offset)
|
||||||
{
|
{
|
||||||
char s[13] = "HelloWorld!\n";
|
char s[13] = "HelloWorld!\n";
|
||||||
int len = sizeof(s);
|
int len = sizeof(s);
|
||||||
|
@ -44,8 +44,8 @@ ssize_t procfile_read(struct file *filePointer, char *buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is called with the /proc file is written. */
|
/* This function is called with the /proc file is written. */
|
||||||
static ssize_t procfile_write(struct file *file, const char *buff, size_t len,
|
static ssize_t procfile_write(struct file *file, const char __user *buff,
|
||||||
loff_t *off)
|
size_t len, loff_t *off)
|
||||||
{
|
{
|
||||||
procfs_buffer_size = len;
|
procfs_buffer_size = len;
|
||||||
if (procfs_buffer_size > PROCFS_MAX_SIZE)
|
if (procfs_buffer_size > PROCFS_MAX_SIZE)
|
||||||
|
|
|
@ -16,12 +16,12 @@
|
||||||
#define PROCFS_MAX_SIZE 2048
|
#define PROCFS_MAX_SIZE 2048
|
||||||
#define PROCFS_ENTRY_FILENAME "buffer2k"
|
#define PROCFS_ENTRY_FILENAME "buffer2k"
|
||||||
|
|
||||||
struct proc_dir_entry *our_proc_file;
|
static struct proc_dir_entry *our_proc_file;
|
||||||
static char procfs_buffer[PROCFS_MAX_SIZE];
|
static char procfs_buffer[PROCFS_MAX_SIZE];
|
||||||
static unsigned long procfs_buffer_size = 0;
|
static unsigned long procfs_buffer_size = 0;
|
||||||
|
|
||||||
static ssize_t procfs_read(struct file *filp, char *buffer, size_t length,
|
static ssize_t procfs_read(struct file *filp, char __user *buffer,
|
||||||
loff_t *offset)
|
size_t length, loff_t *offset)
|
||||||
{
|
{
|
||||||
static int finished = 0;
|
static int finished = 0;
|
||||||
|
|
||||||
|
@ -38,8 +38,8 @@ static ssize_t procfs_read(struct file *filp, char *buffer, size_t length,
|
||||||
pr_debug("procfs_read: read %lu bytes\n", procfs_buffer_size);
|
pr_debug("procfs_read: read %lu bytes\n", procfs_buffer_size);
|
||||||
return procfs_buffer_size;
|
return procfs_buffer_size;
|
||||||
}
|
}
|
||||||
static ssize_t procfs_write(struct file *file, const char *buffer, size_t len,
|
static ssize_t procfs_write(struct file *file, const char __user *buffer,
|
||||||
loff_t *off)
|
size_t len, loff_t *off)
|
||||||
{
|
{
|
||||||
if (len > PROCFS_MAX_SIZE)
|
if (len > PROCFS_MAX_SIZE)
|
||||||
procfs_buffer_size = PROCFS_MAX_SIZE;
|
procfs_buffer_size = PROCFS_MAX_SIZE;
|
||||||
|
@ -51,12 +51,12 @@ static ssize_t procfs_write(struct file *file, const char *buffer, size_t len,
|
||||||
pr_debug("procfs_write: write %lu bytes\n", procfs_buffer_size);
|
pr_debug("procfs_write: write %lu bytes\n", procfs_buffer_size);
|
||||||
return procfs_buffer_size;
|
return procfs_buffer_size;
|
||||||
}
|
}
|
||||||
int procfs_open(struct inode *inode, struct file *file)
|
static int procfs_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
try_module_get(THIS_MODULE);
|
try_module_get(THIS_MODULE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int procfs_close(struct inode *inode, struct file *file)
|
static int procfs_close(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -29,7 +29,7 @@ static struct proc_dir_entry *our_proc_file;
|
||||||
* function.
|
* function.
|
||||||
*/
|
*/
|
||||||
static ssize_t module_output(struct file *file, /* see include/linux/fs.h */
|
static ssize_t module_output(struct file *file, /* see include/linux/fs.h */
|
||||||
char *buf, /* The buffer to put data to
|
char __user *buf, /* The buffer to put data to
|
||||||
(in the user segment) */
|
(in the user segment) */
|
||||||
size_t len, /* The length of the buffer */
|
size_t len, /* The length of the buffer */
|
||||||
loff_t *offset)
|
loff_t *offset)
|
||||||
|
@ -58,7 +58,7 @@ static ssize_t module_output(struct file *file, /* see include/linux/fs.h */
|
||||||
* /proc file.
|
* /proc file.
|
||||||
*/
|
*/
|
||||||
static ssize_t module_input(struct file *file, /* The file itself */
|
static ssize_t module_input(struct file *file, /* The file itself */
|
||||||
const char *buf, /* The buffer with input */
|
const char __user *buf, /* The buffer with input */
|
||||||
size_t length, /* The buffer's length */
|
size_t length, /* The buffer's length */
|
||||||
loff_t *offset) /* offset to file - ignore */
|
loff_t *offset) /* offset to file - ignore */
|
||||||
{
|
{
|
||||||
|
@ -77,10 +77,10 @@ static ssize_t module_input(struct file *file, /* The file itself */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 1 if the file is currently open by somebody */
|
/* 1 if the file is currently open by somebody */
|
||||||
int already_open = 0;
|
static int already_open = 0;
|
||||||
|
|
||||||
/* Queue of processes who want our file */
|
/* Queue of processes who want our file */
|
||||||
DECLARE_WAIT_QUEUE_HEAD(waitq);
|
static DECLARE_WAIT_QUEUE_HEAD(waitq);
|
||||||
|
|
||||||
/* Called when the /proc file is opened */
|
/* Called when the /proc file is opened */
|
||||||
static int module_open(struct inode *inode, struct file *file)
|
static int module_open(struct inode *inode, struct file *file)
|
||||||
|
@ -141,7 +141,7 @@ static int module_open(struct inode *inode, struct file *file)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when the /proc file is closed */
|
/* Called when the /proc file is closed */
|
||||||
int module_close(struct inode *inode, struct file *file)
|
static int module_close(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
/* Set already_open to zero, so one of the processes in the waitq will
|
/* Set already_open to zero, so one of the processes in the waitq will
|
||||||
* be able to set already_open back to one and to open the file. All
|
* be able to set already_open back to one and to open the file. All
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <linux/kernel.h> /* We are doing kernel work */
|
#include <linux/kernel.h> /* We are doing kernel work */
|
||||||
#include <linux/module.h> /* Specifically, a module */
|
#include <linux/module.h> /* Specifically, a module */
|
||||||
|
|
||||||
void cleanup_module()
|
void cleanup_module(void)
|
||||||
{
|
{
|
||||||
pr_info("Short is the life of a kernel module\n");
|
pr_info("Short is the life of a kernel module\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ module_param(sym, ulong, 0644);
|
||||||
|
|
||||||
#endif /* Version < v5.7 */
|
#endif /* Version < v5.7 */
|
||||||
|
|
||||||
unsigned long **sys_call_table;
|
static unsigned long **sys_call_table;
|
||||||
|
|
||||||
/* UID we want to spy on - will be filled from the command line. */
|
/* UID we want to spy on - will be filled from the command line. */
|
||||||
static int uid;
|
static int uid;
|
||||||
|
@ -75,7 +75,7 @@ module_param(uid, int, 0644);
|
||||||
* Another reason for this is that we can not get sys_open.
|
* Another reason for this is that we can not get sys_open.
|
||||||
* It is a static variable, so it is not exported.
|
* It is a static variable, so it is not exported.
|
||||||
*/
|
*/
|
||||||
asmlinkage int (*original_call)(const char *, int, int);
|
static asmlinkage int (*original_call)(const char *, int, int);
|
||||||
|
|
||||||
/* The function we will replace sys_open (the function called when you
|
/* The function we will replace sys_open (the function called when you
|
||||||
* call the open system call) with. To find the exact prototype, with
|
* call the open system call) with. To find the exact prototype, with
|
||||||
|
@ -87,7 +87,7 @@ asmlinkage int (*original_call)(const char *, int, int);
|
||||||
* wreck havoc and require programs to be recompiled, since the system
|
* wreck havoc and require programs to be recompiled, since the system
|
||||||
* calls are the interface between the kernel and the processes).
|
* calls are the interface between the kernel and the processes).
|
||||||
*/
|
*/
|
||||||
asmlinkage int our_sys_open(const char *filename, int flags, int mode)
|
static asmlinkage int our_sys_open(const char *filename, int flags, int mode)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
char ch;
|
char ch;
|
||||||
|
@ -95,7 +95,7 @@ asmlinkage int our_sys_open(const char *filename, int flags, int mode)
|
||||||
/* Report the file, if relevant */
|
/* Report the file, if relevant */
|
||||||
pr_info("Opened file by %d: ", uid);
|
pr_info("Opened file by %d: ", uid);
|
||||||
do {
|
do {
|
||||||
get_user(ch, filename + i);
|
get_user(ch, (char __user *)filename + i);
|
||||||
i++;
|
i++;
|
||||||
pr_info("%c", ch);
|
pr_info("%c", ch);
|
||||||
} while (ch != 0);
|
} while (ch != 0);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user