Re: [PATCH v5] printk: Userspace format enumeration support

From: Petr Mladek
Date: Tue Mar 16 2021 - 07:39:42 EST


On Mon 2021-03-15 12:20:59, Chris Down wrote:
> Petr Mladek writes:
> > > I don't feel strongly that this is more clear though, so maybe you
> > > mean something else?
> >
> > I was pretty tired when reviewing the patch. It was not easy for me
> > to create the mental model of the code. I felt that some other names
> > would have made it easier.
> >
> > Also the tricky pi_next() implementation did not help much. It looks
> > like you changed the code many times to get it working and did not
> > clean it at the end.
>
> No worries. I'm not totally clear on what you're asking for though: do you
> meant that you'd like the SEQ_START_TOKEN logic to only be present for
> pi_start, or to pull out the logic currently in pi_next into another
> function and call it from both, or?
>
> In my mind, pi_start is really just a special case of pi_next, so the code
> flow makes sense to me. I'm happy to change it to whatever you like, but
> it's not immediately obvious to me what that is :-)

Good question! I have missed that pi_start() can be called also with non-zero
pos when seeking.

OK, pi_start() has to handle pos == 0 special way, so let's handle it
there. Call pi_next() only when pos != 0.

The following code should do the job. I took this from my previous reply.
It is already based on the other suggested changes:

static struct pi_entry *pi_get_entry(struct module *mod, int idx)
{
struct pi_entry *entries;
int num_entries;

if (mod) {
entries = mod->entries;
num_entries = num->num_entries;
} else {
entries = vmlinux_entries;
num_entries = vmlinux_num_entries;
}

if (idx >= num_entries)
return NULL;

return entries[idx];
}

static void *pi_next(struct seq_file *s, void *v, loff_t *pos)
{
const struct module *mod = (struct module*)s->file->f_inode->i_private;
struct pi_entry *entry;

entry = pi_get_entry(mod, *pos);
*(pos)++;

return entry;
}

static void *pi_start(struct seq_file *s, loff_t *pos)
{
/*
* Make show() print the header line. Do not update *pos
* because pi_next() still has to return entry on the index zero.
*/
if (*pos == 0)
return SEQ_START_TOKEN;

return pi_next(s, NULL, pos);
}

Best Regards,
Petr