Skip to content

Commit cf1b6d4

Browse files
YuKuai-huaweiliu-song-6
authored andcommitted
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
1 parent 3d8d328 commit cf1b6d4

1 file changed

Lines changed: 22 additions & 78 deletions

File tree

drivers/md/md.c

Lines changed: 22 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -8213,105 +8213,46 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)
82138213
}
82148214

82158215
static void *md_seq_start(struct seq_file *seq, loff_t *pos)
8216+
__acquires(&all_mddevs_lock)
82168217
{
8217-
struct list_head *tmp;
8218-
loff_t l = *pos;
8219-
struct mddev *mddev;
8218+
struct md_personality *pers;
82208219

8221-
if (l == 0x10000) {
8222-
++*pos;
8223-
return (void *)2;
8224-
}
8225-
if (l > 0x10000)
8226-
return NULL;
8227-
if (!l--)
8228-
/* header */
8229-
return (void*)1;
8220+
seq_puts(seq, "Personalities : ");
8221+
spin_lock(&pers_lock);
8222+
list_for_each_entry(pers, &pers_list, list)
8223+
seq_printf(seq, "[%s] ", pers->name);
8224+
8225+
spin_unlock(&pers_lock);
8226+
seq_puts(seq, "\n");
8227+
seq->poll_event = atomic_read(&md_event_count);
82308228

82318229
spin_lock(&all_mddevs_lock);
8232-
list_for_each(tmp,&all_mddevs)
8233-
if (!l--) {
8234-
mddev = list_entry(tmp, struct mddev, all_mddevs);
8235-
if (!mddev_get(mddev))
8236-
continue;
8237-
spin_unlock(&all_mddevs_lock);
8238-
return mddev;
8239-
}
8240-
spin_unlock(&all_mddevs_lock);
8241-
if (!l--)
8242-
return (void*)2;/* tail */
8243-
return NULL;
8230+
8231+
return seq_list_start(&all_mddevs, *pos);
82448232
}
82458233

82468234
static void *md_seq_next(struct seq_file *seq, void *v, loff_t *pos)
82478235
{
8248-
struct list_head *tmp;
8249-
struct mddev *next_mddev, *mddev = v;
8250-
struct mddev *to_put = NULL;
8251-
8252-
++*pos;
8253-
if (v == (void*)2)
8254-
return NULL;
8255-
8256-
spin_lock(&all_mddevs_lock);
8257-
if (v == (void*)1) {
8258-
tmp = all_mddevs.next;
8259-
} else {
8260-
to_put = mddev;
8261-
tmp = mddev->all_mddevs.next;
8262-
}
8263-
8264-
for (;;) {
8265-
if (tmp == &all_mddevs) {
8266-
next_mddev = (void*)2;
8267-
*pos = 0x10000;
8268-
break;
8269-
}
8270-
next_mddev = list_entry(tmp, struct mddev, all_mddevs);
8271-
if (mddev_get(next_mddev))
8272-
break;
8273-
mddev = next_mddev;
8274-
tmp = mddev->all_mddevs.next;
8275-
}
8276-
spin_unlock(&all_mddevs_lock);
8277-
8278-
if (to_put)
8279-
mddev_put(to_put);
8280-
return next_mddev;
8281-
8236+
return seq_list_next(v, &all_mddevs, pos);
82828237
}
82838238

82848239
static void md_seq_stop(struct seq_file *seq, void *v)
8240+
__releases(&all_mddevs_lock)
82858241
{
8286-
struct mddev *mddev = v;
8287-
8288-
if (mddev && v != (void*)1 && v != (void*)2)
8289-
mddev_put(mddev);
8242+
status_unused(seq);
8243+
spin_unlock(&all_mddevs_lock);
82908244
}
82918245

82928246
static int md_seq_show(struct seq_file *seq, void *v)
82938247
{
8294-
struct mddev *mddev = v;
8248+
struct mddev *mddev = list_entry(v, struct mddev, all_mddevs);
82958249
sector_t sectors;
82968250
struct md_rdev *rdev;
82978251

8298-
if (v == (void*)1) {
8299-
struct md_personality *pers;
8300-
seq_printf(seq, "Personalities : ");
8301-
spin_lock(&pers_lock);
8302-
list_for_each_entry(pers, &pers_list, list)
8303-
seq_printf(seq, "[%s] ", pers->name);
8304-
8305-
spin_unlock(&pers_lock);
8306-
seq_printf(seq, "\n");
8307-
seq->poll_event = atomic_read(&md_event_count);
8252+
if (!mddev_get(mddev))
83088253
return 0;
8309-
}
8310-
if (v == (void*)2) {
8311-
status_unused(seq);
8312-
return 0;
8313-
}
83148254

8255+
spin_unlock(&all_mddevs_lock);
83158256
spin_lock(&mddev->lock);
83168257
if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
83178258
seq_printf(seq, "%s : %sactive", mdname(mddev),
@@ -8382,6 +8323,9 @@ static int md_seq_show(struct seq_file *seq, void *v)
83828323
seq_printf(seq, "\n");
83838324
}
83848325
spin_unlock(&mddev->lock);
8326+
spin_lock(&all_mddevs_lock);
8327+
if (atomic_dec_and_test(&mddev->active))
8328+
__mddev_put(mddev);
83858329

83868330
return 0;
83878331
}

0 commit comments

Comments
 (0)