mirror of
https://github.com/torvalds/linux
synced 2024-10-07 11:53:31 +00:00
md: simplify md_seq_ops
Before this patch, the implementation is hacky and hard to understand: 1) md_seq_start set pos to 1; 2) md_seq_show found pos is 1, then print Personalities; 3) md_seq_next found pos is 1, then it update pos to the first mddev; 4) md_seq_show found pos is not 1 or 2, show mddev; 5) md_seq_next found pos is not 1 or 2, update pos to next mddev; 6) loop 4-5 until the last mddev, then md_seq_next update pos to 2; 7) md_seq_show found pos is 2, then print unused devices; 8) md_seq_next found pos is 2, stop; This patch remove the magic value and use seq_list_start/next/stop() directly, and move printing "Personalities" to md_seq_start(), "unsed devices" to md_seq_stop(): 1) md_seq_start print Personalities, and then set pos to first mddev; 2) md_seq_show show mddev; 3) md_seq_next update pos to next mddev; 4) loop 2-3 until the last mddev; 5) md_seq_stop print unsed devices; Signed-off-by: Yu Kuai <yukuai3@huawei.com> Signed-off-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/r/20230927061241.1552837-3-yukuai1@huaweicloud.com
This commit is contained in:
parent
3d8d32873c
commit
cf1b6d4441
100
drivers/md/md.c
100
drivers/md/md.c
|
@ -8213,105 +8213,46 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *md_seq_start(struct seq_file *seq, loff_t *pos)
|
static void *md_seq_start(struct seq_file *seq, loff_t *pos)
|
||||||
|
__acquires(&all_mddevs_lock)
|
||||||
{
|
{
|
||||||
struct list_head *tmp;
|
struct md_personality *pers;
|
||||||
loff_t l = *pos;
|
|
||||||
struct mddev *mddev;
|
|
||||||
|
|
||||||
if (l == 0x10000) {
|
seq_puts(seq, "Personalities : ");
|
||||||
++*pos;
|
spin_lock(&pers_lock);
|
||||||
return (void *)2;
|
list_for_each_entry(pers, &pers_list, list)
|
||||||
}
|
seq_printf(seq, "[%s] ", pers->name);
|
||||||
if (l > 0x10000)
|
|
||||||
return NULL;
|
spin_unlock(&pers_lock);
|
||||||
if (!l--)
|
seq_puts(seq, "\n");
|
||||||
/* header */
|
seq->poll_event = atomic_read(&md_event_count);
|
||||||
return (void*)1;
|
|
||||||
|
|
||||||
spin_lock(&all_mddevs_lock);
|
spin_lock(&all_mddevs_lock);
|
||||||
list_for_each(tmp,&all_mddevs)
|
|
||||||
if (!l--) {
|
return seq_list_start(&all_mddevs, *pos);
|
||||||
mddev = list_entry(tmp, struct mddev, all_mddevs);
|
|
||||||
if (!mddev_get(mddev))
|
|
||||||
continue;
|
|
||||||
spin_unlock(&all_mddevs_lock);
|
|
||||||
return mddev;
|
|
||||||
}
|
|
||||||
spin_unlock(&all_mddevs_lock);
|
|
||||||
if (!l--)
|
|
||||||
return (void*)2;/* tail */
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||||
{
|
{
|
||||||
struct list_head *tmp;
|
return seq_list_next(v, &all_mddevs, pos);
|
||||||
struct mddev *next_mddev, *mddev = v;
|
|
||||||
struct mddev *to_put = NULL;
|
|
||||||
|
|
||||||
++*pos;
|
|
||||||
if (v == (void*)2)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
spin_lock(&all_mddevs_lock);
|
|
||||||
if (v == (void*)1) {
|
|
||||||
tmp = all_mddevs.next;
|
|
||||||
} else {
|
|
||||||
to_put = mddev;
|
|
||||||
tmp = mddev->all_mddevs.next;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (tmp == &all_mddevs) {
|
|
||||||
next_mddev = (void*)2;
|
|
||||||
*pos = 0x10000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
next_mddev = list_entry(tmp, struct mddev, all_mddevs);
|
|
||||||
if (mddev_get(next_mddev))
|
|
||||||
break;
|
|
||||||
mddev = next_mddev;
|
|
||||||
tmp = mddev->all_mddevs.next;
|
|
||||||
}
|
|
||||||
spin_unlock(&all_mddevs_lock);
|
|
||||||
|
|
||||||
if (to_put)
|
|
||||||
mddev_put(to_put);
|
|
||||||
return next_mddev;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void md_seq_stop(struct seq_file *seq, void *v)
|
static void md_seq_stop(struct seq_file *seq, void *v)
|
||||||
|
__releases(&all_mddevs_lock)
|
||||||
{
|
{
|
||||||
struct mddev *mddev = v;
|
status_unused(seq);
|
||||||
|
spin_unlock(&all_mddevs_lock);
|
||||||
if (mddev && v != (void*)1 && v != (void*)2)
|
|
||||||
mddev_put(mddev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int md_seq_show(struct seq_file *seq, void *v)
|
static int md_seq_show(struct seq_file *seq, void *v)
|
||||||
{
|
{
|
||||||
struct mddev *mddev = v;
|
struct mddev *mddev = list_entry(v, struct mddev, all_mddevs);
|
||||||
sector_t sectors;
|
sector_t sectors;
|
||||||
struct md_rdev *rdev;
|
struct md_rdev *rdev;
|
||||||
|
|
||||||
if (v == (void*)1) {
|
if (!mddev_get(mddev))
|
||||||
struct md_personality *pers;
|
|
||||||
seq_printf(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_printf(seq, "\n");
|
|
||||||
seq->poll_event = atomic_read(&md_event_count);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
if (v == (void*)2) {
|
|
||||||
status_unused(seq);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
spin_unlock(&all_mddevs_lock);
|
||||||
spin_lock(&mddev->lock);
|
spin_lock(&mddev->lock);
|
||||||
if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
|
if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
|
||||||
seq_printf(seq, "%s : %sactive", mdname(mddev),
|
seq_printf(seq, "%s : %sactive", mdname(mddev),
|
||||||
|
@ -8382,6 +8323,9 @@ static int md_seq_show(struct seq_file *seq, void *v)
|
||||||
seq_printf(seq, "\n");
|
seq_printf(seq, "\n");
|
||||||
}
|
}
|
||||||
spin_unlock(&mddev->lock);
|
spin_unlock(&mddev->lock);
|
||||||
|
spin_lock(&all_mddevs_lock);
|
||||||
|
if (atomic_dec_and_test(&mddev->active))
|
||||||
|
__mddev_put(mddev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue