[vz8,2/2] ext4: send abort uevent on ext4 journal abort

Submitted by Andrey Ryabinin on Nov. 5, 2020, 5:07 p.m.

Details

Message ID 20201105170720.3413-2-aryabinin@virtuozzo.com
State New
Series "Series without cover letter"
Headers show

Commit Message

Andrey Ryabinin Nov. 5, 2020, 5:07 p.m.
From: Dmitry Monakhov <dmonakhov@openvz.org>

Currenlty error from device result in ext4_abort, but uevent not generated because
ext4_abort() caller's context do not allow GFP_KERNEL memory allocation.
Let's relax submission context requirement and deffer actual uevent submission
to work_queue.  It can be any workqueue I've pick rsv_conversion_wq because it is
already exists.

khorenko@: "system_wq" does not fit here because at the moment of
work execution sb can be already destroyed.
"EXT4_SB(sb)->rsv_conversion_wq" is flushed before sb is destroyed.

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>

[aryabinin rh8 rebase]
Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 fs/ext4/ext4.h  |  2 ++
 fs/ext4/super.c | 10 ++++++++++
 2 files changed, 12 insertions(+)

Patch hide | download patch | download mbox

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 228492c9518f..bbdd7efc8447 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1499,6 +1499,7 @@  struct ext4_sb_info {
 	__u32 s_csum_seed;
 
 	bool s_err_event_sent;
+	bool s_abrt_event_sent;
 
 	/* Reclaim extents from extent status tree */
 	struct shrinker s_es_shrinker;
@@ -3126,6 +3127,7 @@  enum ext4_event_type {
      EXT4_UA_UMOUNT,
      EXT4_UA_REMOUNT,
      EXT4_UA_ERROR,
+     EXT4_UA_ABORT,
      EXT4_UA_FREEZE,
      EXT4_UA_UNFREEZE,
 };
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 3cc979825ec8..00619f45b1c3 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -420,6 +420,9 @@  static void ext4_send_uevent_work(struct work_struct *w)
 	case EXT4_UA_ERROR:
 		ret = add_uevent_var(env, "FS_ACTION=%s", "ERROR");
 		break;
+	case EXT4_UA_ABORT:
+		ret = add_uevent_var(env, "FS_ACTION=%s", "ABORT");
+		break;
 	case EXT4_UA_FREEZE:
 		ret = add_uevent_var(env, "FS_ACTION=%s", "FREEZE");
 		break;
@@ -576,6 +579,9 @@  static void ext4_handle_error(struct super_block *sb)
 	if (!test_opt(sb, ERRORS_CONT)) {
 		journal_t *journal = EXT4_SB(sb)->s_journal;
 
+		if (!xchg(&EXT4_SB(sb)->s_abrt_event_sent, 1))
+			ext4_send_uevent(sb, EXT4_UA_ABORT);
+
 		EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED;
 		if (journal)
 			jbd2_journal_abort(journal, -EIO);
@@ -801,6 +807,10 @@  void __ext4_abort(struct super_block *sb, const char *function,
 
 	if (sb_rdonly(sb) == 0) {
 		ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
+
+		if (!xchg(&EXT4_SB(sb)->s_abrt_event_sent, 1))
+			ext4_send_uevent(sb, EXT4_UA_ABORT);
+
 		EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED;
 		/*
 		 * Make sure updated value of ->s_mount_flags will be visible