Zhao Minmin (1): ext4: report error to userspace by netlink
Zhihao Cheng (1): Add new config 'CONFIG_EXT4_ERROR_REPORT' to control ext3/4 error reporting
arch/arm64/configs/openeuler_defconfig | 1 + arch/x86/configs/openeuler_defconfig | 1 + fs/ext4/Kconfig | 8 +++ fs/ext4/ext4.h | 11 ++++ fs/ext4/super.c | 71 ++++++++++++++++++++++++++ include/uapi/linux/netlink.h | 1 + 6 files changed, 93 insertions(+)
From: Zhao Minmin zhaominmin1@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8TNRU CVE: NA
-------------------------------------------------
Implement the ext3/ext4 file system error report.
This patch is used to implement abnormal alarm of ext3/ext4 filesystem. You can archieve this by setting "FILESYSTEM_MONITOR" or "FILESYSTEM_ALARM" on in configuration file. With this setting, alarm will be raised when ext3/ext4 file system expection occurs.
Signed-off-by: Zhao Minmin zhaominmin1@huawei.com Reviewed-by: Yi Zhang yi.zhang@huawei.com Link: http://hulk.huawei.com/pipermail/kernel.openeuler/2016-March/009711.html Signed-off-by: Wang Hui john.wanghui@huawei.com Signed-off-by: Kefeng Wang wangkefeng.wang@huawei.com
[yebin: cherry-pick this patch from openeuler, commit 6636f4434a9c] conflicts : fs/ext4/super.c fs/ext4/ext4.h
Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com
Conflicts: fs/ext4/super.c
Signed-off-by: Baokun Li libaokun1@huawei.com --- fs/ext4/ext4.h | 9 ++++++ fs/ext4/super.c | 54 +++++++++++++++++++++++++++++++++++- include/uapi/linux/netlink.h | 1 + 3 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 4cb121a3d697..66da5f31ff0c 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -47,6 +47,15 @@
#include <linux/compiler.h>
+#define NL_EXT4_ERROR_GROUP 1 +#define EXT4_ERROR_MAGIC 0xAE32014U +struct ext4_err_msg { + int magic; + char s_id[32]; + unsigned long s_flags; + int ext4_errno; +}; + /* * The fourth extended filesystem constants/structures */ diff --git a/fs/ext4/super.c b/fs/ext4/super.c index df0ed022c53d..46772f69a018 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -57,6 +57,10 @@ #include "mballoc.h" #include "fsmap.h"
+#include <uapi/linux/netlink.h> +#include <net/sock.h> +#include <net/net_namespace.h> + #define CREATE_TRACE_POINTS #include <trace/events/ext4.h>
@@ -84,6 +88,8 @@ static void ext4_unregister_li_request(struct super_block *sb); static void ext4_clear_request_list(void); static struct inode *ext4_get_journal_inode(struct super_block *sb, unsigned int journal_inum); +static void ext4_netlink_send_info(struct super_block *sb, int ext4_errno); +static struct sock *ext4nl; static int ext4_validate_options(struct fs_context *fc); static int ext4_check_opt_consistency(struct fs_context *fc, struct super_block *sb); @@ -678,6 +684,42 @@ static void save_error_info(struct super_block *sb, int error, spin_unlock(&sbi->s_error_lock); }
+static void ext4_netlink_send_info(struct super_block *sb, int ext4_errno) +{ + int size; + sk_buff_data_t old_tail; + struct sk_buff *skb; + struct nlmsghdr *nlh; + struct ext4_err_msg *msg; + + if (ext4nl) { + size = NLMSG_SPACE(sizeof(struct ext4_err_msg)); + skb = alloc_skb(size, GFP_ATOMIC); + if (!skb) { + printk(KERN_ERR "Cannot alloc skb!"); + return; + } + old_tail = skb->tail; + nlh = nlmsg_put(skb, 0, 0, NLMSG_ERROR, size - sizeof(*nlh), 0); + if (!nlh) + goto nlmsg_failure; + msg = (struct ext4_err_msg *)NLMSG_DATA(nlh); + msg->magic = EXT4_ERROR_MAGIC; + memcpy(msg->s_id, sb->s_id, sizeof(sb->s_id)); + msg->s_flags = sb->s_flags; + msg->ext4_errno = ext4_errno; + nlh->nlmsg_len = skb->tail - old_tail; + NETLINK_CB(skb).portid = 0; + NETLINK_CB(skb).dst_group = NL_EXT4_ERROR_GROUP; + netlink_broadcast(ext4nl, skb, 0, NL_EXT4_ERROR_GROUP, + GFP_ATOMIC); + return; +nlmsg_failure: + if (skb) + kfree_skb(skb); + } +} + /* Deal with the reporting of failure conditions on a filesystem such as * inconsistencies detected or read IO failures. * @@ -739,9 +781,12 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error, sb->s_id); }
- if (sb_rdonly(sb) || continue_fs) + if (sb_rdonly(sb)) return;
+ if (continue_fs) + goto out; + ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); /* * Make sure updated value of ->s_mount_flags will be visible before @@ -749,6 +794,8 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error, */ smp_wmb(); sb->s_flags |= SB_RDONLY; +out: + ext4_netlink_send_info(sb, force_ro ? 2 : 1); }
static void update_super_work(struct work_struct *work) @@ -7342,6 +7389,7 @@ wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ]; static int __init ext4_init_fs(void) { int i, err; + struct netlink_kernel_cfg cfg = {.groups = NL_EXT4_ERROR_GROUP,};
ratelimit_state_init(&ext4_mount_msg_ratelimit, 30 * HZ, 64); ext4_li_info = NULL; @@ -7393,6 +7441,9 @@ static int __init ext4_init_fs(void) if (err) goto out;
+ ext4nl = netlink_kernel_create(&init_net, NETLINK_FILESYSTEM, &cfg); + if (!ext4nl) + printk(KERN_ERR "EXT4-fs: Cannot create netlink socket.\n"); return 0; out: unregister_as_ext2(); @@ -7433,6 +7484,7 @@ static void __exit ext4_exit_fs(void) ext4_exit_post_read_processing(); ext4_exit_es(); ext4_exit_pending(); + netlink_kernel_release(ext4nl); }
MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h index e2ae82e3f9f7..ff0b0c8c4590 100644 --- a/include/uapi/linux/netlink.h +++ b/include/uapi/linux/netlink.h @@ -29,6 +29,7 @@ #define NETLINK_RDMA 20 #define NETLINK_CRYPTO 21 /* Crypto layer */ #define NETLINK_SMC 22 /* SMC monitoring */ +#define NETLINK_FILESYSTEM 28 /* filesystem alarm*/
#define NETLINK_INET_DIAG NETLINK_SOCK_DIAG
From: Zhihao Cheng chengzhihao1@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8TNRU CVE: NA
--------------------------------
Add new config 'CONFIG_EXT4_ERROR_REPORT' to control ext3/4 error reporting.
Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com
Conflicts: fs/ext4/super.c
Signed-off-by: Baokun Li libaokun1@huawei.com --- arch/arm64/configs/openeuler_defconfig | 1 + arch/x86/configs/openeuler_defconfig | 1 + fs/ext4/Kconfig | 8 ++++++++ fs/ext4/ext4.h | 2 ++ fs/ext4/super.c | 19 +++++++++++++++++++ 5 files changed, 31 insertions(+)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 8e29cb161800..d4757e2a5f0c 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -6790,6 +6790,7 @@ CONFIG_EXT4_FS=m CONFIG_EXT4_USE_FOR_EXT2=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_ERROR_REPORT=y # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=m # CONFIG_JBD2_DEBUG is not set diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index b3e32559ab62..24f82ad9ff85 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -7993,6 +7993,7 @@ CONFIG_EXT4_FS=m CONFIG_EXT4_USE_FOR_EXT2=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_ERROR_REPORT=y # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=m # CONFIG_JBD2_DEBUG is not set diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index e20d59221fc0..3b095c5aa1d3 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -118,3 +118,11 @@ config EXT4_KUNIT_TESTS to the KUnit documentation in Documentation/dev-tools/kunit/.
If unsure, say N. + +config EXT4_ERROR_REPORT + bool "Ext4 error reporting by netlink" + depends on EXT4_FS && NET + default n + help + Implement the ext3/ext4 file system error report. Report error to + userspace by netlink diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 66da5f31ff0c..a87cdb53198f 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -47,6 +47,7 @@
#include <linux/compiler.h>
+#ifdef CONFIG_EXT4_ERROR_REPORT #define NL_EXT4_ERROR_GROUP 1 #define EXT4_ERROR_MAGIC 0xAE32014U struct ext4_err_msg { @@ -55,6 +56,7 @@ struct ext4_err_msg { unsigned long s_flags; int ext4_errno; }; +#endif
/* * The fourth extended filesystem constants/structures diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 46772f69a018..eb6e68cfe1f5 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -57,9 +57,11 @@ #include "mballoc.h" #include "fsmap.h"
+#ifdef CONFIG_EXT4_ERROR_REPORT #include <uapi/linux/netlink.h> #include <net/sock.h> #include <net/net_namespace.h> +#endif
#define CREATE_TRACE_POINTS #include <trace/events/ext4.h> @@ -88,8 +90,10 @@ static void ext4_unregister_li_request(struct super_block *sb); static void ext4_clear_request_list(void); static struct inode *ext4_get_journal_inode(struct super_block *sb, unsigned int journal_inum); +#ifdef CONFIG_EXT4_ERROR_REPORT static void ext4_netlink_send_info(struct super_block *sb, int ext4_errno); static struct sock *ext4nl; +#endif static int ext4_validate_options(struct fs_context *fc); static int ext4_check_opt_consistency(struct fs_context *fc, struct super_block *sb); @@ -684,6 +688,7 @@ static void save_error_info(struct super_block *sb, int error, spin_unlock(&sbi->s_error_lock); }
+#ifdef CONFIG_EXT4_ERROR_REPORT static void ext4_netlink_send_info(struct super_block *sb, int ext4_errno) { int size; @@ -719,6 +724,7 @@ static void ext4_netlink_send_info(struct super_block *sb, int ext4_errno) kfree_skb(skb); } } +#endif
/* Deal with the reporting of failure conditions on a filesystem such as * inconsistencies detected or read IO failures. @@ -781,11 +787,16 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error, sb->s_id); }
+#ifdef CONFIG_EXT4_ERROR_REPORT if (sb_rdonly(sb)) return;
if (continue_fs) goto out; +#else + if (sb_rdonly(sb) || continue_fs) + return; +#endif
ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); /* @@ -794,8 +805,10 @@ static void ext4_handle_error(struct super_block *sb, bool force_ro, int error, */ smp_wmb(); sb->s_flags |= SB_RDONLY; +#ifdef CONFIG_EXT4_ERROR_REPORT out: ext4_netlink_send_info(sb, force_ro ? 2 : 1); +#endif }
static void update_super_work(struct work_struct *work) @@ -7389,7 +7402,9 @@ wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ]; static int __init ext4_init_fs(void) { int i, err; +#ifdef CONFIG_EXT4_ERROR_REPORT struct netlink_kernel_cfg cfg = {.groups = NL_EXT4_ERROR_GROUP,}; +#endif
ratelimit_state_init(&ext4_mount_msg_ratelimit, 30 * HZ, 64); ext4_li_info = NULL; @@ -7441,9 +7456,11 @@ static int __init ext4_init_fs(void) if (err) goto out;
+#ifdef CONFIG_EXT4_ERROR_REPORT ext4nl = netlink_kernel_create(&init_net, NETLINK_FILESYSTEM, &cfg); if (!ext4nl) printk(KERN_ERR "EXT4-fs: Cannot create netlink socket.\n"); +#endif return 0; out: unregister_as_ext2(); @@ -7484,7 +7501,9 @@ static void __exit ext4_exit_fs(void) ext4_exit_post_read_processing(); ext4_exit_es(); ext4_exit_pending(); +#ifdef CONFIG_EXT4_ERROR_REPORT netlink_kernel_release(ext4nl); +#endif }
MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/3819 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/E...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/3819 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/E...