From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753665AbcBXLxk (ORCPT ); Wed, 24 Feb 2016 06:53:40 -0500 Received: from mailout3.w1.samsung.com ([210.118.77.13]:28526 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752954AbcBXLxc (ORCPT ); Wed, 24 Feb 2016 06:53:32 -0500 X-AuditID: cbfec7f4-f79026d00000418a-15-56cd99b9ce1d 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 4/8] kmsg: add additional buffers support to memory class Date: Wed, 24 Feb 2016 12:53:17 +0100 Message-id: <1456314801-32738-5-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+NgFvrPLMWRmVeSWpSXmKPExsVy+t/xy7o7Z54NM2hYa2UxZ/0aNou/k46x W2ycsZ7V4smBdkaLpr+vWCyaF69ns7jwPMCi8dNcZovLG86xWax4cZjRYvP3DjaLhW1LWCwu 75rDZrF6bQOrxaGzP1gsjl36x2ix8P9mJosPEzewWfxafpTR4uCyWWwOIh733/xl8fj9axKj x85Zd9k9VvxZz+axaVUnm8eJGb9ZPPbPXcPusbhvMqtH35ZVjB5nFhxh9/i8Sc7j9f5DjB4f 13t6bN+9nCWAL4rLJiU1J7MstUjfLoEr49Z15YJTWhWrDi5mbGDcpNTFyMkhIWAi8endDUYI W0ziwr31bF2MXBxCAksZJW6umc0OkhASaGSSaN0nB2KzCehLnD83hQmkSERgFZPEw9Yp7CAO s8B2RolTBx6ygVQJC/hIPPmzAMxmEVCVuDT/KtgKXgFXiSttz1gg1slJnDw2mbWLkYODU8BN 4vT7MohlrhLfdxxmmcDIu4CRYRWjaGppckFxUnquoV5xYm5xaV66XnJ+7iZGSLR82cG4+JjV IUYBDkYlHt4HG86ECbEmlhVX5h5ilOBgVhLhjZt2NkyINyWxsiq1KD++qDQntfgQozQHi5I4 79xd70OEBNITS1KzU1MLUotgskwcnFINjKxTf278luKY3st5gum2BmeqB+PEMyVFxSzazK0H fjt+MS/csb1+barNDy0effbDESb61uFZeS4XI50mNans3Wj7Imdvmayu7Tv1w7f7Lr84dSNE q3vrP+Fntm4Mp1R0O/f3yVo+Y39SKBq6UsqTMep6WO/KZVK3Yi7LHef68+/t08uMH9f0KbEU ZyQaajEXFScCACrivP6SAgAA Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Marcin Niesluchowski Memory class does not support additional kmsg buffers. Add additional kmsg buffers support to: * devnode() callback of "mem" class * file operations of major "mem" character device Signed-off-by: Marcin Niesluchowski Signed-off-by: Paul Osmialowski [Rebased kmsg patch v5 on Linux 4.5-rc5] Signed-off-by: Kazimierz Krosman --- drivers/char/mem.c | 27 ++++++++++++++++++++------- include/linux/printk.h | 32 ++++++++++++++++++++++++++++++++ kernel/printk/kmsg.c | 42 ++++++++++++++++++++++++++++++++++++++++++ kernel/printk/printk.c | 1 + kernel/printk/printk.h | 1 + 5 files changed, 96 insertions(+), 7 deletions(-) diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 4f6f94c..aa68923 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -799,9 +799,6 @@ static const struct memdev { [7] = { "full", 0666, &full_fops, 0 }, [8] = { "random", 0666, &random_fops, 0 }, [9] = { "urandom", 0666, &urandom_fops, 0 }, -#ifdef CONFIG_PRINTK - [11] = { "kmsg", 0644, &kmsg_fops, 0 }, -#endif }; static int memory_open(struct inode *inode, struct file *filp) @@ -811,7 +808,7 @@ static int memory_open(struct inode *inode, struct file *filp) minor = iminor(inode); if (minor >= ARRAY_SIZE(devlist)) - return -ENXIO; + return kmsg_memory_open(inode, filp); dev = &devlist[minor]; if (!dev->fops) @@ -833,16 +830,28 @@ static const struct file_operations memory_fops = { static char *mem_devnode(struct device *dev, umode_t *mode) { - if (mode && devlist[MINOR(dev->devt)].mode) - *mode = devlist[MINOR(dev->devt)].mode; + int minor = MINOR(dev->devt); + + if (!mode) + goto out; + + if (minor >= ARRAY_SIZE(devlist)) { + kmsg_mode(minor, mode); + goto out; + } + + if (devlist[minor].mode) + *mode = devlist[minor].mode; +out: return NULL; } -static struct class *mem_class; +struct class *mem_class; static int __init chr_dev_init(void) { int minor; + struct device *kmsg; if (register_chrdev(MEM_MAJOR, "mem", &memory_fops)) printk("unable to get major %d for memory devs\n", MEM_MAJOR); @@ -866,6 +875,10 @@ static int __init chr_dev_init(void) NULL, devlist[minor].name); } + kmsg = init_kmsg(KMSG_MINOR, 0644); + if (IS_ERR(kmsg)) + return PTR_ERR(kmsg); + return tty_init(); } diff --git a/include/linux/printk.h b/include/linux/printk.h index 9ccbdf2..342e9d0 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -417,8 +417,40 @@ do { \ no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) #endif +#define KMSG_MINOR 11 + +struct file; +struct inode; + +#ifdef CONFIG_PRINTK + +extern struct class *mem_class; + extern const struct file_operations kmsg_fops; +extern struct device *init_kmsg(int minor, umode_t mode); +extern int kmsg_memory_open(struct inode *inode, struct file *filp); +extern int kmsg_mode(int minor, umode_t *mode); + +#else + +static inline struct device *init_kmsg(int minor, umode_t mode) +{ + return NULL; +} + +static inline int kmsg_memory_open(struct inode *inode, struct file *filp) +{ + return -ENXIO; +} + +static inline int kmsg_mode(int minor, umode_t *mode) +{ + return -ENXIO; +} + +#endif + enum { DUMP_PREFIX_NONE, DUMP_PREFIX_ADDRESS, diff --git a/kernel/printk/kmsg.c b/kernel/printk/kmsg.c index dbb4a6b..b5e07ff 100644 --- a/kernel/printk/kmsg.c +++ b/kernel/printk/kmsg.c @@ -16,6 +16,9 @@ #include #include #include +#include +#include +#include #include @@ -386,6 +389,45 @@ const struct file_operations kmsg_fops = { .release = devkmsg_release, }; +/* Should be used for device registration */ +struct device *init_kmsg(int minor, umode_t mode) +{ + log_buf.minor = minor; + log_buf.mode = mode; + return device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor), + NULL, "kmsg"); +} + +int kmsg_memory_open(struct inode *inode, struct file *filp) +{ + filp->f_op = &kmsg_fops; + + return kmsg_fops.open(inode, filp); +} + +int kmsg_mode(int minor, umode_t *mode) +{ + int ret = -ENXIO; + struct log_buffer *log_b; + + if (minor == log_buf.minor) { + *mode = log_buf.mode; + return 0; + } + + rcu_read_lock(); + list_for_each_entry_rcu(log_b, &log_buf.list, list) { + if (log_b->minor == minor) { + *mode = log_b->mode; + ret = 0; + break; + } + } + rcu_read_unlock(); + + return ret; +} + static DEFINE_SPINLOCK(dump_list_lock); static LIST_HEAD(dump_list); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index b99403b..d8626ee 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -177,6 +177,7 @@ struct log_buffer log_buf = { .next_idx = 0, .clear_seq = 0, .clear_idx = 0, + .mode = 0, .minor = 0, }; diff --git a/kernel/printk/printk.h b/kernel/printk/printk.h index 4eefde5..e5c8a46 100644 --- a/kernel/printk/printk.h +++ b/kernel/printk/printk.h @@ -130,6 +130,7 @@ struct log_buffer { u64 clear_seq; u32 clear_idx; + int mode; /* mode of device */ int minor; /* minor representing buffer device */ #endif }; -- 1.9.1