Re: [PATCH 4/4] reiserfs: rework reiserfs_snprintf to not abuse va_list (as much)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed 11-04-18 12:49:25, Rasmus Villemoes wrote:
> On 2018-04-11 12:01, Jan Kara wrote:
> > On Tue 10-04-18 19:56:14, Rasmus Villemoes wrote:
> >> Here's an idea that does require rewriting all the existing
> >> reiserfs_warning etc. calls, but avoids all the fragile vararg handling
> >> and adds proper compile-time format string checking:
> >>
> >> Have reiserfs_warning (and friends) be a macro that expands to
> >>
> >>   reiserfs_printf_start();
> >>   __reiserfs_warning(the arguments);
> >>   reiserfs_printf_stop();
> >>
> >> where printf_start would take a spinlock and reset some bookkeeping
> >> variables. Then all the sprintf_de_head etc. helpers would have a
> >> prototype like
> >>
> >> const char *sprintf_de_head(struct reiserfs_de_head *deh)
> >>
> >> and they would print their output to the current error_buf, updating the
> >> above-mentioned bookkeeping variable(s) and return a pointer to the
> >> start of the area they printed to. So
> >>
> >>   reiserfs_warning("bla %a", deh)
> >>
> >> would get changed to
> >>
> >>   reiserfs_warning("bla %s", sprintf_de_head(deh))
> >>
> >> Basically, the current error_buf would only be used for holding the
> >> result of the custom specifiers, everything else goes directly to
> >> printk's output buffer, so no need to make error_buf larger (a single
> >> printk is limited to 1024 bytes anyway...), and fmt_buf goes away
> >> completely. That reduction in static footprint should make up for at
> >> least some of the bloat caused by the extra code the new
> >> reiserfs_warning would generate. Also, I don't think this should make us
> >> hold the spinlock (much) longer than is currently the case, and
> >> trivially solves the problem of not actually holding the spinlock when
> >> passing the error_buf to printk.
> > 
> > So I don't see how this would work for more complex warnings like:
> > 
> >    reiserfs_warning("bla %*d foo %a bar %llx %a", width, number, deh,
> > 		    another_number, deh2)
> >
> 
> all the %a and other current custom specifiers would be rewritten as %s,
> and the corresponding arguments would be wrapped with an appropriate
> call to the custom formatter, so that example would be
> 
>   reiserfs_warning("bla %*d foo %s bar %llx %s", width, number,
>          sprintf_de_head(deh), another_number, sprintf_de_head(deh2))
> 
> And sprintf_de_head would be something like
> 
> char *sprintf_de_head(struct reiserfs_de_head *deh)
> {
>   buf = cur_err_buf;
>   len = snprintf(buf, compute-whats-left, "whatever", deh->this, deh->that);
>   cur_err_buf += len+1;
>   return buf;
> }
> 
> except one would need to handle the case of overflowing err_buf a little
> better. In reiserfs_printf_start, we'd take the spinlock and set
> cur_err_buf = err_buf. reiserfs_printf_stop would simply unlock the
> spinlock. It doesn't matter what order gcc evaluates the
> reiserfs_warning arguments.
> 
> Internally, __reiserfs_warning is mostly just a pr_warn. Well, maybe for
> the _warning case one wants to add another level of macro machinery to
> handle the __func__ and unique-id strings, but that's simple enough.
> Actually, perhaps __reiserfs_warning-the-function would go away
> completely and just be a direct pr_warn call.
> 
> Yes, as I said, it does require rewriting all (well, those using custom
> specifiers) existing reiserfs_warning calls, but considering the
> diffstat of the current patch set, I don't think it's that bad. And we'd
> get proper type checking and format string checking, so there's not much
> risk. Sure, the rewriting may require some clever coccinelle script, but
> it's definitely doable. We don't even need to match the specifiers with
> the arguments; any struct reiserfs_de_head * that is passed to a
> reiserfs_warning should just be wrapped in sprintf_de_head(), and after
> that it's just s/%a/%s/. The __printf attribute will catch anything this
> misses.

OK, I understand now. So basically ripping out all the smarts (except for
buffer space handling) out of reiserfs_warning() and putting them into the
caller. That certainly works although it's quite some work - 175 warnings to
go through.

								Honza
-- 
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR
--
To unsubscribe from this list: send the line "unsubscribe reiserfs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux File System Development]     [Linux BTRFS]     [Linux NFS]     [Linux Filesystems]     [Ext4 Filesystem]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Resources]

  Powered by Linux