From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756828AbcBXLyo (ORCPT ); Wed, 24 Feb 2016 06:54:44 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:30625 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753482AbcBXLxi (ORCPT ); Wed, 24 Feb 2016 06:53:38 -0500 X-AuditID: cbfec7f5-f79b16d000005389-a9-56cd99bc68db From: Kazimierz Krosman To: akpm@linux-foundation.org, peter@hurleysoftware.com, tj@kernel.org, vvs@virtuozzo.com, corbet@lwn.net, arnd@arndb.de, pmladek@suse.cz, gregkh@linuxfoundation.org, daniel@zonque.org, kay.sievers@vrfy.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-api@vger.kernel.org Cc: k.lewandowsk@samsung.com, k.krosman@samsung.com, m.niesluchow@samsung.com, richard.weinberger@gmail.com, b.zolnierkie@samsung.com, luto@amacapital.net, knhoon.baik@samsung.com Subject: [PATCH v6 7/8] kmsg: add ioctl for kmsg* devices operating on buffers Date: Wed, 24 Feb 2016 12:53:20 +0100 Message-id: <1456314801-32738-8-git-send-email-k.krosman@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1456314801-32738-1-git-send-email-k.krosman@samsung.com> References: <1456314801-32738-1-git-send-email-k.krosman@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpkkeLIzCtJLcpLzFFi42I5/e/4Zd09M8+GGSw9zW8xZ/0aNou/k46x W2ycsZ7V4smBdkaLpr+vWCyaF69ns7jwPMCi8dNcZovLG86xWax4cZjRYvP3DjaLhW1LWCwu 75rDZrF6bQOrxaGzP1gsjl36x2ix8P9mJosPEzewWfxafpTR4uCyWWwOIh733/xl8fj9axKj x85Zd9k9VvxZz+axaVUnm8eJGb9ZPPbPXcPusbhvMqtH35ZVjB5nFhxh9/i8Sc7j9f5DjB4f 13t6bN+9nCWAL4rLJiU1J7MstUjfLoEro6tlK0vBZNWK7it3WRoYt8h1MXJySAiYSNyfc4MJ whaTuHBvPVsXIxeHkMBSRomm5dcYIZxGJokF8+aBVbEJ6EucPzeFCSQhIrCKSeJh6xR2EIdZ YDujxKkDD9lAqoQF/CSmtZ9hBLFZBFQlFl14wApi8wq4Sizf8pwdYp+cxMljk4HiHBycAm4S p9+XgYSFgEq+7zjMMoGRdwEjwypG0dTS5ILipPRcI73ixNzi0rx0veT83E2MkIj5uoNx6TGr Q4wCHIxKPLwPNpwJE2JNLCuuzD3EKMHBrCTCGzftbJgQb0piZVVqUX58UWlOavEhRmkOFiVx 3pm73ocICaQnlqRmp6YWpBbBZJk4OKUaGFv+t1fv+XK1qnGVW0Va8UW5gsuBRwzPnd17+92L 36dPnBRfvE8hy9H4ZuzpnT9e8Rk9OWLyne+ayTLdGf5Bd14HzLz9QqTjYmie4bVXG854Hdxs tCNr65uslLmcfjsfGMvZn2xjEvQ0uvcuYOXDsE99wqkMt20Mlbe/rT5yrVhlx1nLiDM+B7SU WIozEg21mIuKEwGzHb6ZlAIAAA== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Marcin Niesluchowski There is no possibility to clear additional kmsg buffers, get size of them or know what size should be passed to read file operation (too small size causes it to retrun -EINVAL). Add following ioctls which solve those issues: * KMSG_CMD_GET_BUF_SIZE * KMSG_CMD_GET_READ_SIZE_MAX * KMSG_CMD_CLEAR Signed-off-by: Marcin Niesluchowski Signed-off-by: Paul Osmialowski [Rebased kmsg patch v5 on Linux 4.5-rc5] Signed-off-by: Kazimierz Krosman --- Documentation/ioctl/ioctl-number.txt | 2 +- include/uapi/linux/kmsg_ioctl.h | 15 ++++++++++ kernel/printk/kmsg.c | 57 ++++++++++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt index 4949aac..c133fb2 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt @@ -319,7 +319,7 @@ Code Seq#(hex) Include File Comments 0xB1 00-1F PPPoX 0xB3 00 linux/mmc/ioctl.h -0xBB 00-02 uapi/linux/kmsg_ioctl.h +0xBB 00-83 uapi/linux/kmsg_ioctl.h 0xC0 00-0F linux/usb/iowarrior.h 0xCA 00-0F uapi/misc/cxl.h 0xCA 80-8F uapi/scsi/cxlflash_ioctl.h diff --git a/include/uapi/linux/kmsg_ioctl.h b/include/uapi/linux/kmsg_ioctl.h index 96e7930..bfd9cd3 100644 --- a/include/uapi/linux/kmsg_ioctl.h +++ b/include/uapi/linux/kmsg_ioctl.h @@ -27,4 +27,19 @@ struct kmsg_cmd_buffer_add { struct kmsg_cmd_buffer_add) #define KMSG_CMD_BUFFER_DEL _IOW(KMSG_IOCTL_MAGIC, 0x01, int) +/* + * A ioctl interface for kmsg* devices. + * + * KMSG_CMD_GET_BUF_SIZE: Retrieve cyclic log buffer size associated with + * device. + * KMSG_CMD_GET_READ_SIZE_MAX: Retrieve max size of data read by kmsg read + * operation. + * KMSG_CMD_CLEAR: Clears cyclic log buffer. After that operation + * there is no data to read from buffer unless + * logs are written. + */ +#define KMSG_CMD_GET_BUF_SIZE _IOR(KMSG_IOCTL_MAGIC, 0x80, __u32) +#define KMSG_CMD_GET_READ_SIZE_MAX _IOR(KMSG_IOCTL_MAGIC, 0x81, __u32) +#define KMSG_CMD_CLEAR _IO(KMSG_IOCTL_MAGIC, 0x82) + #endif diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c index 4bf36cd..9ba3989 100644 --- a/kernel/printk/kmsg.c +++ b/kernel/printk/kmsg.c @@ -247,8 +247,9 @@ static loff_t kmsg_llseek(struct log_buffer *log_b, struct file *file, } /* * The first record after the last SYSLOG_ACTION_CLEAR, - * like issued by 'dmesg -c'. Reading /dev/kmsg itself - * changes no global state, and does not clear anything. + * like issued by 'dmesg -c' or KMSG_CMD_CLEAR ioctl + * command. Reading /dev/kmsg itself changes no global + * state, and does not clear anything. */ user->idx = log_b->clear_idx; user->seq = log_b->clear_seq; @@ -391,6 +392,56 @@ static int devkmsg_open(struct inode *inode, struct file *file) return ret; } +static long kmsg_ioctl(struct log_buffer *log_b, unsigned int cmd, + unsigned long arg) +{ + void __user *argp = (void __user *)arg; + static const u32 read_size_max = CONSOLE_EXT_LOG_MAX; + + switch (cmd) { + case KMSG_CMD_GET_BUF_SIZE: + if (copy_to_user(argp, &log_b->len, sizeof(u32))) + return -EFAULT; + break; + case KMSG_CMD_GET_READ_SIZE_MAX: + if (copy_to_user(argp, &read_size_max, sizeof(u32))) + return -EFAULT; + break; + case KMSG_CMD_CLEAR: + if (!capable(CAP_SYSLOG)) + return -EPERM; + raw_spin_lock_irq(&log_b->lock); + log_b->clear_seq = log_b->next_seq; + log_b->clear_idx = log_b->next_idx; + raw_spin_unlock_irq(&log_b->lock); + break; + default: + return -ENOTTY; + } + return 0; +} + +static long devkmsg_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + long ret = -ENXIO; + int minor = iminor(file->f_inode); + struct log_buffer *log_b; + + if (minor == log_buf.minor) + return kmsg_ioctl(&log_buf, cmd, arg); + + rcu_read_lock(); + list_for_each_entry_rcu(log_b, &log_buf.list, list) { + if (log_b->minor == minor) { + ret = kmsg_ioctl(log_b, cmd, arg); + break; + } + } + rcu_read_unlock(); + return ret; +} + static int devkmsg_release(struct inode *inode, struct file *file) { struct devkmsg_user *user = file->private_data; @@ -409,6 +460,8 @@ const struct file_operations kmsg_fops = { .write_iter = devkmsg_write, .llseek = devkmsg_llseek, .poll = devkmsg_poll, + .unlocked_ioctl = devkmsg_ioctl, + .compat_ioctl = devkmsg_ioctl, .release = devkmsg_release, }; -- 1.9.1