Unverified Commit 218ebf01 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!3819 support ext3/ext4 netlink error report.

Merge Pull Request from: @ci-robot 
 
PR sync from: Baokun Li <libaokun1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/E2NQRR6J34AYUN6O4MYBSHNSUSYEEXIY/ 
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


-- 
2.31.1
 
https://gitee.com/openeuler/kernel/issues/I8TNRU 
 
Link:https://gitee.com/openeuler/kernel/pulls/3819

 

Reviewed-by: default avatarzhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents 5b6a8b03 9f5c1700
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6806,6 +6806,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
+1 −0
Original line number Diff line number Diff line
@@ -8003,6 +8003,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
+8 −0
Original line number Diff line number Diff line
@@ -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
+11 −0
Original line number Diff line number Diff line
@@ -47,6 +47,17 @@

#include <linux/compiler.h>

#ifdef CONFIG_EXT4_ERROR_REPORT
#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;
};
#endif

/*
 * The fourth extended filesystem constants/structures
 */
+71 −0
Original line number Diff line number Diff line
@@ -57,6 +57,12 @@
#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>

@@ -84,6 +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);
@@ -678,6 +688,44 @@ 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;
	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);
	}
}
#endif

/* Deal with the reporting of failure conditions on a filesystem such as
 * inconsistencies detected or read IO failures.
 *
@@ -739,8 +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");
	/*
@@ -749,6 +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)
@@ -7342,6 +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;
@@ -7393,6 +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();
@@ -7433,6 +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");
Loading