2024-01-09 13:44:16

by Yu Kuai

[permalink] [raw]
Subject: [PATCH] md: fix md_seq_ops() regressions

From: Yu Kuai <[email protected]>

Commit cf1b6d4441ff ("md: simplify md_seq_ops") introduce following
regressions:

1) If list all_mddevs is emptly, personalities and unused devices won't
be showed to user anymore.
2) If seq_file buffer overflowed from md_seq_show(), then md_seq_start()
will be called again, hence personalities will be showed to user
again.
3) If seq_file buffer overflowed from md_seq_stop(), seq_read_iter()
doesn't handle this, hence unused devices won't be showed to user.

Fix above problems by print personalities and unused devices in
md_seq_show(), as it used to be.

Fixes: cf1b6d4441ff ("md: simplify md_seq_ops")

Signed-off-by: Yu Kuai <[email protected]>
---
drivers/md/md.c | 40 +++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index e351e6c51cc7..ff3057c787c1 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -8135,6 +8135,19 @@ static void status_unused(struct seq_file *seq)
seq_printf(seq, "\n");
}

+static void status_personalities(struct seq_file *seq)
+{
+ struct md_personality *pers;
+
+ seq_puts(seq, "Personalities : ");
+ spin_lock(&pers_lock);
+ list_for_each_entry(pers, &pers_list, list)
+ seq_printf(seq, "[%s] ", pers->name);
+
+ spin_unlock(&pers_lock);
+ seq_puts(seq, "\n");
+}
+
static int status_resync(struct seq_file *seq, struct mddev *mddev)
{
sector_t max_sectors, resync, res;
@@ -8276,20 +8289,10 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)
static void *md_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(&all_mddevs_lock)
{
- struct md_personality *pers;
-
- seq_puts(seq, "Personalities : ");
- spin_lock(&pers_lock);
- list_for_each_entry(pers, &pers_list, list)
- seq_printf(seq, "[%s] ", pers->name);
-
- spin_unlock(&pers_lock);
- seq_puts(seq, "\n");
seq->poll_event = atomic_read(&md_event_count);
-
spin_lock(&all_mddevs_lock);

- return seq_list_start(&all_mddevs, *pos);
+ return seq_list_start_head(&all_mddevs, *pos);
}

static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos)
@@ -8300,16 +8303,23 @@ static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static void md_seq_stop(struct seq_file *seq, void *v)
__releases(&all_mddevs_lock)
{
- status_unused(seq);
spin_unlock(&all_mddevs_lock);
}

static int md_seq_show(struct seq_file *seq, void *v)
{
- struct mddev *mddev = list_entry(v, struct mddev, all_mddevs);
+ struct mddev *mddev;
sector_t sectors;
struct md_rdev *rdev;

+ if (v == &all_mddevs) {
+ status_personalities(seq);
+ if (list_empty(&all_mddevs))
+ status_unused(seq);
+ return 0;
+ }
+
+ mddev = list_entry(v, struct mddev, all_mddevs);
if (!mddev_get(mddev))
return 0;

@@ -8385,6 +8395,10 @@ static int md_seq_show(struct seq_file *seq, void *v)
}
spin_unlock(&mddev->lock);
spin_lock(&all_mddevs_lock);
+
+ if (mddev == list_last_entry(&all_mddevs, struct mddev, all_mddevs))
+ status_unused(seq);
+
if (atomic_dec_and_test(&mddev->active))
__mddev_put(mddev);

--
2.39.2



2024-01-09 19:15:25

by Song Liu

[permalink] [raw]
Subject: Re: [PATCH] md: fix md_seq_ops() regressions

On Tue, Jan 9, 2024 at 5:43 AM Yu Kuai <[email protected]> wrote:
>
> From: Yu Kuai <[email protected]>
>
> Commit cf1b6d4441ff ("md: simplify md_seq_ops") introduce following
> regressions:
>
> 1) If list all_mddevs is emptly, personalities and unused devices won't
> be showed to user anymore.
> 2) If seq_file buffer overflowed from md_seq_show(), then md_seq_start()
> will be called again, hence personalities will be showed to user
> again.
> 3) If seq_file buffer overflowed from md_seq_stop(), seq_read_iter()
> doesn't handle this, hence unused devices won't be showed to user.
>
> Fix above problems by print personalities and unused devices in
> md_seq_show(), as it used to be.
>
> Fixes: cf1b6d4441ff ("md: simplify md_seq_ops")
>
> Signed-off-by: Yu Kuai <[email protected]>

Applied to md-6.8 branch. (Yes, I am trying to make some changes to the
branches we use. )

Thanks,
Song